package com.ht.medicaltreatment.serial

import androidx.collection.arrayMapOf
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.UiMessageUtils
import com.kongqw.serialportlibrary.SerialPortFinder
import com.kongqw.serialportlibrary.SerialPortManager
import com.kongqw.serialportlibrary.listener.OnOpenSerialPortListener
import com.kongqw.serialportlibrary.listener.OnSerialPortDataListener
import com.xgst.land.bean.MessageScanBean
import com.xgst.land.utils.ByteUtil
import com.xgst.land.utils.CRCUtils
import com.xgst.land.utils.MessageKey
import com.xgst.land.utils.UIDUitls
import com.xgst.land.utils.runOnMain
import java.io.File
import java.text.SimpleDateFormat
import java.util.Timer
import kotlin.concurrent.schedule

/**
 * 3A0400400382 盘存HF
 * 3A030007C1   运行状态      3a090007 [00 01] 00000000ca
 * 3a03004284   获取HF数据:   3a0b0042 [6caf44a9500104e0] 17
 * 3a030008ce   切换上位机类型
 *
 * 3A04003003F2  盘存UHF
 *
 * 3A030032F4    获取UHF数据  3a 13 00 32 【行02  列00】 29 00 【300833b2ddd9014000000037】 04   没有数据 3A 04 00 32 00 F3
 */
object SerialPortUtils {
    lateinit var mSerialPortManager: SerialPortManager
    private lateinit var saveUHF:ByteArray
    private lateinit var saveHF:ByteArray
    private lateinit var stopUHF:ByteArray
    private lateinit var readUHF:ByteArray
    private lateinit var readHF:ByteArray
    private lateinit var state:ByteArray
    private lateinit var chooseAndroidState:ByteArray
    private val commandMap = arrayMapOf(
        Pair("3A030007C1","运行状态"),
        Pair("3A0400400382","盘存HF指令"),
        Pair("3A03004284","获取HF数据"),
        Pair("3A04003001F0","盘存UHF"),
        Pair("3A030032F4","获取UHF数据"),
        Pair("3A030008CE","切换上位机类型")
    )
    //是否超高频
    private var isUHF = true
    private var UHF_DELAY = 10*1000L

    /**
     * 初始化设备列表
     */
    fun initDevice() {
        //切换上位机类型
        val ChooseState = byteArrayOf(0x3A.toByte(), 0x03.toByte(), 0x00.toByte(), 0x08.toByte())
        chooseAndroidState = CRCUtils.byteAddToByte(ChooseState,CRCUtils.getCrcData(ChooseState))

        val serialPortFinder = SerialPortFinder()
        val devices = serialPortFinder.devices
        if (devices == null || devices.size == 0) {
            LogUtils.i("获取不到串口设备")
            return
        }
        mSerialPortManager = SerialPortManager()

        //打开串口的监听
        mSerialPortManager.setOnOpenSerialPortListener(object : OnOpenSerialPortListener {
            override fun onSuccess(device: File?) {
                LogUtils.i("打开串口成功${device?.absoluteFile}")
                //切换到Android类型
                Timer().schedule(1000){
                    mSerialPortManager.sendBytes(chooseAndroidState)
                    LogUtils.i("发送切换类型指令")
                }
            }

            override fun onFail(device: File?, status: OnOpenSerialPortListener.Status?) {
                when(status){
                    OnOpenSerialPortListener.Status.NO_READ_WRITE_PERMISSION -> LogUtils.i("没有读写权限")
                    else -> LogUtils.i("打开串口失败")
                }
            }
        })

        //串口数据通信监听
        mSerialPortManager.setOnSerialPortDataListener(object : OnSerialPortDataListener {
            override fun onDataReceived(bytes: ByteArray) {
                runOnMain {
                    processingData(bytes)
                }
            }

            override fun onDataSent(bytes: ByteArray) {
                val command = ByteUtil.bytes2HexStr(bytes)
                if(commandMap.containsKey(command)){
                    LogUtils.i("${TimeUtils.getNowString(SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"))} 发送[${commandMap[command]}]指令:${command}")
                }else{
                    LogUtils.i("${TimeUtils.getNowString(SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"))} 发送的指令:${command}")
                }
            }
        })

        //打开串口
        mSerialPortManager.openSerialPort(File("/dev/ttyS4"), 115200)

        //运行状体(检测是否有数据)
        val UHFState = byteArrayOf(0x3A.toByte(), 0x03.toByte(), 0x00.toByte(), 0x07.toByte())
        state = CRCUtils.byteAddToByte(UHFState,CRCUtils.getCrcData(UHFState))

        //开始盘存超高频
        val UHFSave = byteArrayOf(0x3A.toByte(), 0x04.toByte(), 0x00.toByte(), 0x30.toByte(), 0x01.toByte())
        saveUHF = CRCUtils.byteAddToByte(UHFSave,CRCUtils.getCrcData(UHFSave))
        //开始盘存高频
        val HFSave = byteArrayOf(0x3A.toByte(), 0x04.toByte(), 0x00.toByte(), 0x40.toByte(), 0x03.toByte())
        saveHF = CRCUtils.byteAddToByte(HFSave,CRCUtils.getCrcData(HFSave))
        //停止盘存
        val UHFStop = byteArrayOf(0x3A.toByte(), 0x03.toByte(), 0x00.toByte(), 0x31.toByte())
        stopUHF = CRCUtils.byteAddToByte(UHFStop,CRCUtils.getCrcData(UHFStop))
        //读取UHF盘存
        val UHFRead = byteArrayOf(0x3A.toByte(), 0x03.toByte(), 0x00.toByte(), 0x32.toByte())
        readUHF = CRCUtils.byteAddToByte(UHFRead,CRCUtils.getCrcData(UHFRead))

        //读取HF盘存
        val HFRead = byteArrayOf(0x3A.toByte(), 0x03.toByte(), 0x00.toByte(), 0x42.toByte())
        readHF = CRCUtils.byteAddToByte(HFRead,CRCUtils.getCrcData(HFRead))
    }

    private fun processingData(bytes: ByteArray) {
        val data = CRCUtils.bytes2HexString(bytes)
        LogUtils.i("${TimeUtils.getNowString(SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"))}  接收到的指令:$data")
        if(data == "3a04003000f1"){
            //盘存UHF，收到的正常反馈指令
            //Timer().schedule(UHF_DELAY){ checkData() }
            return
        }
        if(bytes.size >= 5 && bytes[0] == 0x3A.toByte() && bytes[1] == 0x09.toByte()&& bytes[3] == 0x07.toByte()){
            //获取运行状态 3a 09 00 07 [00 00 00 01 00 00] ca
            if(isUHF){
                if(bytes[4] == 0x01.toByte()){
                    //UHF有值， 获取数据
                    readUHF()
                }else if(bytes[4] == 0x00.toByte()){
                    sendMsg("",0,0)
                }
            }else{
                if(bytes[5] == 0x01.toByte()){
                    //HF有值，获取数据
                    readHF()
                }else if(bytes[5] == 0x00.toByte()){
                    sendMsg("",0,0)
                }
            }
        }else if(bytes.size > 10 && bytes[0] == 0x3A.toByte() && bytes[1] == 0x13.toByte()&& bytes[3] == 0x32.toByte()){
            //获取UHF盘存数据  3a 13 00 32  [02 01 3a 30]  [30 08 33 b2 dd d9 01 40 00 00 00 12] 03
            //行
            val row = bytes[4].toInt()
            //列
            val col = bytes[5].toInt()
            val uid = data.substring(16,data.length-2)
            sendMsg(uid,row,col)
            //检查是否还有数据
            readUHF()
        }else if(bytes.size > 10 && bytes[0] == 0x3A.toByte() && bytes[3] == 0x42.toByte()){
            //获取HF盘存数据  3a0b0042 6caf44a9500104e0 17
            var uid = data.substring(7,data.length-2)
            uid = UIDUitls.sort(uid)
            sendMsg(uid,0,0)
        }else if(bytes.size == 6 && bytes[0] == 0x3A.toByte() && bytes[3] == 0x32.toByte() && bytes[4] == 0x01.toByte()){
            readUHF()
        }else if(data == "3a04003200f3"){
            //UHF 读取不到数据后，返回这个指令
            sendMsg("",0,0)
        }else if(data.startsWith("3a130") && data.length <= 10 ){
            LogUtils.i("粘包：$data")
            readUHF()
        }
        //3a04003200f3 UHF  没有数据了
    }

    private fun sendMsg(uid: String, row: Int, col: Int) {
        UiMessageUtils.getInstance().send(MessageKey.SCAN_ID, MessageScanBean(uid,row,col))
    }

    /**
     * 超高频
     */
    fun startUHF(){
        isUHF = true
        mSerialPortManager.sendBytes(saveUHF)
    }

    /**
     * 高频
     */
    fun startHF(){
        isUHF = false
        mSerialPortManager.sendBytes(saveHF)
        Timer().schedule(1000){
            checkData()
        }
    }

    fun stopUHF(){
        mSerialPortManager.sendBytes(stopUHF)
    }

    fun readUHF(){
        mSerialPortManager.sendBytes(readUHF)
    }

    fun readHF(){
        mSerialPortManager.sendBytes(readHF)
    }

    fun checkData(){
        mSerialPortManager.sendBytes(state)
    }

    /**
     * 关闭串口
     */
    fun close(){
        mSerialPortManager.closeSerialPort()
    }

    fun open(){
        mSerialPortManager.openSerialPort(File("/dev/ttyS4"), 115200)
    }
}